﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using Etalk.Library;
namespace EtalkServer
{
    public partial class FrmMain : Form
    {
        private IPAddress serverIP;
        private IPEndPoint ipPoint;
        private Socket socket;
        private Thread thead;
        private Thread clientThread;//client的服务
       
        private bool keepalive = true; //是否为活动
        public  SocketCollection AllSocket;
        private int Port;
        public FrmMain()
        {
            InitializeComponent();
            txtIPAddress.Text = System.Configuration.ConfigurationManager.AppSettings["ServerIP"];
            txtIPPort.Value = Convert.ToDecimal(System.Configuration.ConfigurationManager.AppSettings["ServerProt"]);
            Comm.RemoveClientEvent += new RemoveClientHandler(RemoveClient);
            Thread.CurrentThread.IsBackground = true;
        }

        private void StartListening()
        {
            serverIP = IPAddress.Parse(txtIPAddress.Text.Trim());
            try
            {
                ipPoint = new IPEndPoint(serverIP, Convert.ToInt32(txtIPPort.Value));
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Bind(ipPoint);
                socket.Listen(30);//监听是否有连接传入，指定挂起的连接队列的最大值为30
                AllSocket = new SocketCollection();//新建一个ArrayList类型用以存储所有的client
                AllSocket.TraceEvent += new TraceHandler(Trace); //Trace跟踪信息
                //更改控件状态
                this.Invoke(new EventHandler(delegate(object sender, EventArgs e)
                {
                    cmdConn.Enabled = false;
                    cmdCancel.Enabled = true;
                    txtState.Text = "启动";
                }));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            while (true)
            {
                try
                {
                    Socket itmeSoc = socket.Accept();
                    ParameterizedThreadStart newClinet = new ParameterizedThreadStart(ClientService);
                    clientThread = new Thread(newClinet);
                    clientThread.IsBackground = true;
                    clientThread.Start(itmeSoc);
                }
                catch (SocketException sEX)
                {
                    Panny.Logger.ServerLog.writeLog("StartListening() " + sEX.Message);
                }
                catch (Exception ex)
                {

                }
            }
        }

        //开启服务
        private void cmdConn_Click(object sender, EventArgs e)
        {
            Port = Convert.ToInt32(txtIPPort.Value);
            thead = new Thread(new ThreadStart(StartListening));
            thead.Start();
            //myTimer  = new System.Timers.Timer(1000);
            //myTimer.Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
            //myTimer.Enabled =true;
        }
        public void ClientService(object objSoc)
        {
            Socket newClientSoc = (Socket)objSoc;
            bool keepOn = true;
            while (keepOn)
            {
                byte[] byteArray = new byte[100];
                try
                {
                    newClientSoc.Receive(byteArray);
                }
                catch (SocketException ex)
                {
                    this.ClientAborting(newClientSoc,ref keepOn);
                    break;
                }
                string data = System.Text.Encoding.UTF8.GetString(byteArray).TrimEnd(new char[] { '\0' });

                if (data.Length <=0)
                {
                    RemoveClient(AllSocket.Find(newClientSoc));
                    return;
                }

                //解析发送的数据
                string[] arrData = data.Split(new char[] { '|' });

                //if (arrData.Length < 2 )
                //{
                //    RemoveClient(AllSocket.Find(newClientSoc));
                //    return;
                //}
                switch (arrData[0])
                {
                    case "PRIV":
                        if (AllSocket.FindByKey(arrData[2]) != null)
                        {
                            Comm.SendDataToClient(AllSocket.FindByKey(arrData[2]), data);//给对方发
                            string msgContent = "SELF|" + arrData[1] + "|" + arrData[arrData.Length - 1].ToString() + "";
                            Comm.SendDataToClient(AllSocket.FindByKey(arrData[1]), msgContent);//给自己发
                        }
                        else
                        {
                            string strMsg = "GONE|{0}";
                            Comm.SendDataToClient(AllSocket.FindByKey(arrData[1]), string.Format(strMsg, arrData[2]));
                        }
                        break;
                    case "CONN":
                        CommandConn(BindClient(newClientSoc, arrData),arrData);
                        Comm.SendDataToClient(newClientSoc, "已经连接");
                        break;
                    case "LOGIN":
                        CommandLogin(BindClient(newClientSoc, arrData), arrData);
                       // Comm.SendDataToClient(newClientSoc, "已经连接");
                        break;
                    case "<policy-file-request/>": //flash 安全沙箱
                        string s = "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\0";
                        Comm.SendDataToClient(newClientSoc, s);
                        break;
                    case "<policy-file-ssquest/>":
                        string msgStr = "握手成功";
                        break;
                    default:
                         Comm.SendDataToClient(newClientSoc,"参数错误"+data);
                         break;
                }
              
            }
        }

        public void ClientAborting(Socket socketObj,ref bool keepOn)
        {
            try
            {
                lock (AllSocket)
                {
                    foreach (Client clientItem in AllSocket.List)
                    {
                        //if (clientItem.ToString().Contains("Unable to evaluate expression"))
                        //    break;
                        if (clientItem.Host == socketObj.RemoteEndPoint)
                        {
                            //删除客户端列表对应客户端
                            listClient.BeginInvoke(new EventRemoveItem(RemoveItem), listClient, clientItem.Host.ToString());
                            //更新用户数
                            statusBar1.BeginInvoke(new EventStatusValue(SetStatusValue), txtClientCount, listClient.Items.Count.ToString());
                            AllSocket.Remove(clientItem);

                            //给正在连接的对方发送消息. 提示此客户端已经关闭连接
                            socketObj.Close();
                            keepOn = false;
                            break;
                        }
                    }

                }
            }
            catch (Exception e)
            {
                Panny.Logger.ServerLog.writeLog(e.Message);
            }

        }

        #region 输出到控件
        //设置状态栏信息
        delegate void EventStatusValue(StatusBarPanel panelObj,string text);
        public void SetStatusValue(StatusBarPanel panelObj, string text)
        {
            panelObj.Text = text;
        }
            
        //删除LISTVEW控件的 ITEM.
       delegate void EventRemoveItem(ListView obj,string key);
       private void RemoveItem(ListView listViewObj, string key)
      {
          foreach (ListViewItem item in listViewObj.Items)
          {
              if (item.Tag.ToString() == key)
              {
                  listViewObj.Items.Remove(item);
                  break;
              }
          }

      }

        //添加到控件
        delegate void EventAddListViewItem(ListView view, ListViewItem item);
        private void AddViewItem(ListView view, ListViewItem item)
        {
            view.Items.Insert(0, item);
        }
        
       
        #endregion

      
        private void cmdCancel_Click(object sender, EventArgs e)
        {
            try
            {
                //socket.Shutdown(SocketShutdown.Both);
                socket.Close();
                socket = null;
                cmdConn.Enabled =true ;
                cmdCancel.Enabled = false;
                txtState.Text ="停止";
                thead.Abort();
            }
            catch (Exception ex)
            {
                MessageBox.Show("S:Close Socket Error" + ex.Message);
            }
        }

        /// <summary>
        /// 服务器发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdSendToClient_Click(object sender, EventArgs e)
        {
             foreach(ListViewItem item in listClient.SelectedItems)
             {
                 foreach (Client cItem in AllSocket.List)
                 {
                     if (item.Tag.ToString() == cItem.Host.ToString())
                     {
                         //Comm.SendDataToClient(cItem, "PRIV|"+cItem.Name+"|Easydp-Server|"+txtSendClient.Text);
                         Comm.SendDataToClient(cItem, "PRIV|Easydp-Server|" + txtSendClient.Text);
                     }
                 }
             }
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                foreach (Client item in AllSocket.List)
                {
                    if (item.Sock != null)
                    {
                        item.Sock.Close();
                        item.Host = null;
                        item.CLThread.Abort();
                    }
                }
                if (thead != null)
                {
                    //socket.Close();
                    //socket = null;
                    thead.Abort();
                }
               // Application.Exit();
            }
            catch (Exception ex)
            {
                MessageBox.Show("S:Close Socket Error" + ex.Message);
            }
        }
    }
}